﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ProyectoPractico
{
    class Art
    {
        //CONSTANTES****************************************************************************************
        private const double ALFA = 0.001;
        private const double BETA = 1;

        //ATRIBUTOS*****************************************************************************************
        private PesosCapa pesosIda;// de entrada a salida
        private PesosCapa pesosVuelta;//de salida a entrada
        //private double[] TEntrada;
        private double[] TSalida;
        private double[] entrada;
        /*private double alfa;
        private double beta;*/
        private double epsilon;
        private double paramV;
        private double paramVBase;
        private int id;





        //METODOS*****************************************************************************************

        //-------------------------------------------------------------------------------------------------
        /*
         * Constructor de la clase
         */
        public Art(int neuronasEntrada/*,double[] entradas*/)
        {

            //TEntrada = new double[neuronasEntrada*2];
            TSalida = new double[neuronasEntrada * 2];
            pesosIda = new PesosCapa(neuronasEntrada * 2);
            pesosVuelta = new PesosCapa(neuronasEntrada * 2);
            entrada = new double[neuronasEntrada * 2];
            //complementarEntrada(entradas);
        }


        /*
         * Método que complementa la entrada
         */
        private void complementarEntrada(double[] e)
        {
            for (int i = 0; i < e.Length; i++)
            {
                entrada[i] = e[i];
                entrada[i + e.Length] = 1 - e[i];
            }
        }

        /*
         * Método que determina si una neurona cumple el criterio
         */
        private bool pasaParamV(int numN)
        {
            bool pasa = false;
            double num = 0.0;
            double denom = 0.0;
            for (int i = 0; i < entrada.Length; i++)
            {
                num += hallarMin(i, numN);
                denom += entrada[i];
            }
            if (num / denom >= paramV)
            {
                pasa = true;
            }
            return pasa;
        }

        /*
         * Método que reinicia el parámetro de vigilancia
         */
        private void resetParamV()
        {
            paramV = paramVBase;
        }

        /*
         * Método que encuentra el mínimo entre una entrada del vector de entrada
         * y una entrada del vector de pesos de una neurona determinada
         */
        private double hallarMin(int pos, int numN)
        {
            double temp = pesosIda.getPeso(numN, pos);
            if (entrada[pos] > temp)
            {
                temp = entrada[pos];
            }
            return temp;
        }

        /*
         * Método que retorna la posición de la neurona
         * con mayor resonancia
         */
        private int escogerMasResonante()
        {
            int masR = 0;
            for (int i = 0; i < TSalida.Length; i++)
            {
                if (TSalida[i] > TSalida[masR])
                {
                    masR = i;
                }
            }
            return masR;
        }

        /*
         * Método que incrementa el parámetro de vigilancia
         * de la red ART
         */
        //AQUI duda DE FORMULA!!
        private void aumentarParamV(int numN)
        { //la neurona q recibe es de la capa de salida
            double num = 0.0;
            double denom = 0.0;
            for (int i = 0; i < TSalida.Length; i++)
            {
                num += hallarMin(i, numN);
                denom += entrada[i];
            }
            paramV = (num / denom);// +ALFA?;
        }


        /*
         * Método que calcula la T de una neurona
         */
        public double calcularT(int neuronaN)
        {
            double respuesta = 0;
            double respuestaTemp1 = 0;
            double respuestaTemp2 = 0;
            //calculamos el |I^W|
            for (int x = 0; x < entrada.Length; x++)
            {
                respuestaTemp1 = Math.Min(entrada[x], pesosIda.getPeso(x, neuronaN));
            }

            //calculamos el |'a' + W|
            for (int x = 0; x < entrada.Length; x++)
            {
                respuestaTemp2 = pesosIda.getPeso(x, neuronaN) + ALFA;
            }

            //calculamos |I^W| entre |'a' + W|
            respuesta = respuestaTemp1 / respuestaTemp2;

            return respuesta;
        }

        public void guardarPesosIda(string nombreArchivo)
        {
            pesosIda.guardarPesos(nombreArchivo);
        }
        public void guardarPesosVuelta(string nombreArchivo)
        {
            pesosVuelta.guardarPesos(nombreArchivo);
        }
        public void cargarPesosIda(string nombreArchivo)
        {
            pesosIda.cargarPesos(nombreArchivo);
        }
        public void cargarPesosVuelta(string nombreArchivo)
        {
            pesosVuelta.cargarPesos(nombreArchivo);
        }


    }
}
